package study.activiti.l_groupTask;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.junit.Test;

/**  
 * @Name: GroupTaskTest
 * @Description: 组任务测试类
 * @Author: 李超
 * @Create Date: 2016-12-16
 */
public class GroupTaskTest {
	
	//流程引擎
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine() ;
	
	//1、部署流程定义、启动流程实例
	@Test
	public void deploymentProcessDeginitionAndStartProcessInstance() {
		//流程资源输入流
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("groupTask.bpmn") ;
		InputStream inputStreamPng = this.getClass().getResourceAsStream("groupTask.png");
		//部署流程定义
		processEngine.getRepositoryService()
					 .createDeployment()
					 .name("组任务")
					 .addInputStream("groupTask.bpmn", inputStreamBpmn)
					 .addInputStream("groupTask.png", inputStreamPng)
					 .deploy() ;
		//流程定义的key
		String processDefinitionKey = "groupTask" ;
		//定义流程变量，指定组任务的办理人
		Map<String, Object> variables = new HashMap<String, Object>() ;
		variables.put("userIds", "大大,小小,中中") ;
		//启动流程实例，同时设置流程变量，用来指定组任务的办理人
		ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey,variables) ;
		System.out.println("流程实例启动成功");
		System.out.println("流程实例id:" + pi.getId());
		System.out.println("##############################");
	}
	
	
	/**
	 * 2、查询个人任务列表
	 * 说明：因为为组任务，正在指定的任务表中的assignee（任务办理人）字段为空，查询不到结果
	 * assignee为空时：
	 * 		1、没有指定任务的办理人;
	 * 		2、该任务是一个组任务;
	 */
	@Test
	public void queryMyPersonalTask() {
		//任务办理人
		String assignee = "大大" ;
		//查询个人个人列表
		List<Task> list = processEngine.getTaskService()
					 .createTaskQuery()
					 .taskAssignee(assignee) //指定个人任务查询
					 .list() ;
		if(list != null && list.size() > 0) {
			for (Task task : list) {
				System.out.println("任务id:" + task.getId());
				System.out.println("任务名称:" + task.getName());
				System.out.println("任务办理人:" + task.getAssignee());
				System.out.println("任务创建时间:" + task.getCreateTime());
				System.out.println("执行对象id:" + task.getExecutionId());
				System.out.println("###################################");
			}
		}
	}
	
	/**
	 * 拾取任务:将组任务分配给个人任务
	 * 		1、从组任务的候选人中选出一个人办理当前的组任务
	 * 		2、从非组任务中选择一个办理当前的组任务
	 */
	@Test
	public void claim() {
		//任务id
		String taskId = "215009" ;
		//组候选人作为任务办理人
		String userId = "大大" ;
		//非组候选成员作为任务的办理人
		//String userId = "小F" ;
		//指定当前正在指定的组任务的办理人
		processEngine.getTaskService().claim(taskId, userId) ;
	}
	
	/**
	 * 3、查询组任务列表
	 * 		条件：
	 * 			1、任务办理人字段为空，即该任务是一个组任务
	 * 			2、待查询人员是组任务的候选人，即在组任务的办理人员表中的Type_字段为cadidate
	 * 			3、人员名称
	 * 		当将组任务分配给个人任务之后，无法再根据组任务的候选人查询组任务列表信息
	 * 		解决办法：可以将个人任务回退到组任务
	 * 		前提：这个个人任务之前一定是一个组任务
	 */
	@Test
	public void queryMyGroupTask() {
		//组任务候选人
		String candidateUser = "大大" ;
		//查询组任务列表
		List<Task> list = processEngine.getTaskService()
					 .createTaskQuery()
					 .taskCandidateUser(candidateUser) //指定组任务查询
					 .list() ;
		if(list != null && list.size() > 0) {
			for (Task task : list) {
				System.out.println("任务id:" + task.getId());
				System.out.println("任务名称:" + task.getName());
				System.out.println("任务办理人:" + task.getAssignee());
				System.out.println("任务创建时间:" + task.getCreateTime());
				System.out.println("执行对象id:" + task.getExecutionId());
				System.out.println("###################################");
			}
		}
	}
	
	/**
	 * 回退任务：将个人任务回退到组任务
	 * 前提：这个个人任务之前一定是一个组任务
	 */
	@Test 
	public void setAssigneeIsNull() {
		//任务id
		String taskId = "215009" ;
		//将个人任务办理人置空，如果这个任务之前是一个组任务，将回退到之前的组任务
		processEngine.getTaskService().setAssignee(taskId, null) ;
	}
	
	//4、查询正在执行的组任务办理成员列表
	@Test
	public void queryGroupTaskUsers() {
		//任务id
		String taskId = "215009" ;
		//根据任务id，查询正在执行的组任务成员列表
		List<IdentityLink> list = processEngine.getTaskService()
					 .getIdentityLinksForTask(taskId) ; //根据任务id查询正在执行的任务办理人列表
		if(list != null && list.size() > 0) {
			for (IdentityLink identityLink : list) {
				System.out.println("任务id:" + taskId);
				System.out.println("任务办理人类型:" + identityLink.getType());
				System.out.println("任务办理人:" + identityLink.getUserId());
				System.out.println("######################################");
			}
		}
	}
	
	//向组任务中添加成员
	@Test
	public void addGroupUser() {
		//任务id
		String taskId = "215009" ;
		//新成员
		String userId = "框框" ;
		//向组任务中添加成员
		processEngine.getTaskService().addCandidateUser(taskId, userId) ;
	}
	
	//从组任务中删除成员
	@Test
	public void deleteGroupUser() {
		//任务id
		String taskId = "215009" ;
		//待删除成员
		//从组任务中删除成员
		String userId = "框框" ;
		processEngine.getTaskService().deleteCandidateUser(taskId, userId) ;
	}
	
	//5、完成任务
	@Test
	public void completeGroupTask() {
		//任务id
		String taskId = "215009" ;
		//根据任务id，完成组任务
		processEngine.getTaskService().complete(taskId) ;
		System.out.println("完成任务，任务id:" + taskId);
	}
	
	//6、查询组任务办理成员历史列表
	@Test
	public void queryGroupTaskHisUsers() {
		//任务id
		String taskId = "215009" ;
		//流程实例id
		//String processInstanceId = "182505" ;
		//根据任务id，查询历史任务办理成员列表
		List<HistoricIdentityLink> list = processEngine.getHistoryService()
					 .getHistoricIdentityLinksForTask(taskId) ; //根据任务id，查询历史任务办理成员列表
//					 .getHistoricIdentityLinksForProcessInstance(processInstanceId) ; //根据流程实例id，查询历史任务办理成员列表
		if(list != null && list.size() > 0) {
			for (HistoricIdentityLink hil : list) {
				System.out.println("任务id:" + taskId);
				System.out.println("任务办理人类型:" + hil.getType());
				System.out.println("任务办理人:" + hil.getUserId());
				System.out.println("######################################");
			}
		}
	}
	
}
